{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Time</th>\n",
       "      <th>V1</th>\n",
       "      <th>V2</th>\n",
       "      <th>V3</th>\n",
       "      <th>V4</th>\n",
       "      <th>V5</th>\n",
       "      <th>V6</th>\n",
       "      <th>V7</th>\n",
       "      <th>V8</th>\n",
       "      <th>V9</th>\n",
       "      <th>...</th>\n",
       "      <th>V21</th>\n",
       "      <th>V22</th>\n",
       "      <th>V23</th>\n",
       "      <th>V24</th>\n",
       "      <th>V25</th>\n",
       "      <th>V26</th>\n",
       "      <th>V27</th>\n",
       "      <th>V28</th>\n",
       "      <th>Amount</th>\n",
       "      <th>Class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.0</td>\n",
       "      <td>-1.359807</td>\n",
       "      <td>-0.072781</td>\n",
       "      <td>2.536347</td>\n",
       "      <td>1.378155</td>\n",
       "      <td>-0.338321</td>\n",
       "      <td>0.462388</td>\n",
       "      <td>0.239599</td>\n",
       "      <td>0.098698</td>\n",
       "      <td>0.363787</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.018307</td>\n",
       "      <td>0.277838</td>\n",
       "      <td>-0.110474</td>\n",
       "      <td>0.066928</td>\n",
       "      <td>0.128539</td>\n",
       "      <td>-0.189115</td>\n",
       "      <td>0.133558</td>\n",
       "      <td>-0.021053</td>\n",
       "      <td>149.62</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.0</td>\n",
       "      <td>1.191857</td>\n",
       "      <td>0.266151</td>\n",
       "      <td>0.166480</td>\n",
       "      <td>0.448154</td>\n",
       "      <td>0.060018</td>\n",
       "      <td>-0.082361</td>\n",
       "      <td>-0.078803</td>\n",
       "      <td>0.085102</td>\n",
       "      <td>-0.255425</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.225775</td>\n",
       "      <td>-0.638672</td>\n",
       "      <td>0.101288</td>\n",
       "      <td>-0.339846</td>\n",
       "      <td>0.167170</td>\n",
       "      <td>0.125895</td>\n",
       "      <td>-0.008983</td>\n",
       "      <td>0.014724</td>\n",
       "      <td>2.69</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.0</td>\n",
       "      <td>-1.358354</td>\n",
       "      <td>-1.340163</td>\n",
       "      <td>1.773209</td>\n",
       "      <td>0.379780</td>\n",
       "      <td>-0.503198</td>\n",
       "      <td>1.800499</td>\n",
       "      <td>0.791461</td>\n",
       "      <td>0.247676</td>\n",
       "      <td>-1.514654</td>\n",
       "      <td>...</td>\n",
       "      <td>0.247998</td>\n",
       "      <td>0.771679</td>\n",
       "      <td>0.909412</td>\n",
       "      <td>-0.689281</td>\n",
       "      <td>-0.327642</td>\n",
       "      <td>-0.139097</td>\n",
       "      <td>-0.055353</td>\n",
       "      <td>-0.059752</td>\n",
       "      <td>378.66</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1.0</td>\n",
       "      <td>-0.966272</td>\n",
       "      <td>-0.185226</td>\n",
       "      <td>1.792993</td>\n",
       "      <td>-0.863291</td>\n",
       "      <td>-0.010309</td>\n",
       "      <td>1.247203</td>\n",
       "      <td>0.237609</td>\n",
       "      <td>0.377436</td>\n",
       "      <td>-1.387024</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.108300</td>\n",
       "      <td>0.005274</td>\n",
       "      <td>-0.190321</td>\n",
       "      <td>-1.175575</td>\n",
       "      <td>0.647376</td>\n",
       "      <td>-0.221929</td>\n",
       "      <td>0.062723</td>\n",
       "      <td>0.061458</td>\n",
       "      <td>123.50</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2.0</td>\n",
       "      <td>-1.158233</td>\n",
       "      <td>0.877737</td>\n",
       "      <td>1.548718</td>\n",
       "      <td>0.403034</td>\n",
       "      <td>-0.407193</td>\n",
       "      <td>0.095921</td>\n",
       "      <td>0.592941</td>\n",
       "      <td>-0.270533</td>\n",
       "      <td>0.817739</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.009431</td>\n",
       "      <td>0.798278</td>\n",
       "      <td>-0.137458</td>\n",
       "      <td>0.141267</td>\n",
       "      <td>-0.206010</td>\n",
       "      <td>0.502292</td>\n",
       "      <td>0.219422</td>\n",
       "      <td>0.215153</td>\n",
       "      <td>69.99</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 31 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   Time        V1        V2        V3        V4        V5        V6        V7  \\\n",
       "0   0.0 -1.359807 -0.072781  2.536347  1.378155 -0.338321  0.462388  0.239599   \n",
       "1   0.0  1.191857  0.266151  0.166480  0.448154  0.060018 -0.082361 -0.078803   \n",
       "2   1.0 -1.358354 -1.340163  1.773209  0.379780 -0.503198  1.800499  0.791461   \n",
       "3   1.0 -0.966272 -0.185226  1.792993 -0.863291 -0.010309  1.247203  0.237609   \n",
       "4   2.0 -1.158233  0.877737  1.548718  0.403034 -0.407193  0.095921  0.592941   \n",
       "\n",
       "         V8        V9  ...         V21       V22       V23       V24  \\\n",
       "0  0.098698  0.363787  ...   -0.018307  0.277838 -0.110474  0.066928   \n",
       "1  0.085102 -0.255425  ...   -0.225775 -0.638672  0.101288 -0.339846   \n",
       "2  0.247676 -1.514654  ...    0.247998  0.771679  0.909412 -0.689281   \n",
       "3  0.377436 -1.387024  ...   -0.108300  0.005274 -0.190321 -1.175575   \n",
       "4 -0.270533  0.817739  ...   -0.009431  0.798278 -0.137458  0.141267   \n",
       "\n",
       "        V25       V26       V27       V28  Amount  Class  \n",
       "0  0.128539 -0.189115  0.133558 -0.021053  149.62      0  \n",
       "1  0.167170  0.125895 -0.008983  0.014724    2.69      0  \n",
       "2 -0.327642 -0.139097 -0.055353 -0.059752  378.66      0  \n",
       "3  0.647376 -0.221929  0.062723  0.061458  123.50      0  \n",
       "4 -0.206010  0.502292  0.219422  0.215153   69.99      0  \n",
       "\n",
       "[5 rows x 31 columns]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 导入数据集\n",
    "data = pd.read_csv('creditcard.csv')\n",
    "data.head()\n",
    "\n",
    "# v1 -  v28 也没有具体说这些列表达什么含义，对这些数据都做了一部分处理 \n",
    "# 通过PC的降维操作，进行特征的压缩，相当于这些特征都是直接用的特征\n",
    "# Amount 表示交易的金额\n",
    "# Class 等于0，表示正样本， Clsss等于1 表示负样本"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    284315\n",
      "1       492\n",
      "Name: Class, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZsAAAETCAYAAADge6tNAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAGdJJREFUeJzt3X+0XWV95/H3xwAVRAElIoZgUGNbZCpiirROW60VAq2CLpmCTkkdWjqKbbWdGdFlC9UyS2e12DJWWigZAX8gYlWq2EhRy9hBJSgDRHRIESUmhUiA8Pvnd/7Yz62Hy825J4F9T3Lyfq111jn7u5+997NDyOfuZz93n1QVkiT16Unj7oAkafIZNpKk3hk2kqTeGTaSpN4ZNpKk3hk2kqTeGTbSJiT5SpLf2oLtKsnz++jTDMc6JclHhqxfleTlc9EXaZgdxt0BaZgkNwJ7AQ8PlF9QVWvH06NtS1W9cLY2SRYB3wN2rKqH+u6Ttk9e2Whb8Oqq2nXg9ZigSeIPTlsp/9sIDBtto5IsasNVxyf5AfClVv9kkn9NckeSy5K8cGCbRw2LJfnNJF8dWH5Vku+0bT8IZMjx5yV5V5J/SXJnkiuTLJyh3a8m+VaSjUluSnLKwLonJ/lIkluT3J7kiiR7DfTthrbv7yV545A/jp2SnNvarkqyZOAYNyb5lfb54CQrW19uTnJaa3ZZe789yV1Jfi7Jk5K8O8n3k9zS9r/bwH6Pa+tuTfJH045zSpIL27ltBH6zHfvydp7rknwwyU4D+6skb0lyfTuP9yZ5XttmY5ILBttr22PYaFv3S8BPA4e15S8Ai4FnAt8EPjrKTpLsCXwKeDewJ/AvwMuGbPIHwLHAEcDTgP8E3DNDu7uB44DdgV8F3pzkqLZuGbAbsBB4BvCfgXuTPAU4HTi8qp4K/Dxw1ZC+vAY4vx3jIuCDm2j3l8BfVtXTgOcBF7T6L7b33duV4+XAb7bXK4DnArtO7TfJ/sCHgDcCe7dzWDDtWEcCF7Y+fZRuGPTtdH+2Pwe8EnjLtG2WAi8BDgH+G3BmO8ZC4AC6P29towwbbQs+034ivj3JZ6atO6Wq7q6qewGqanlV3VlV9wOnAC8a/Il8iCOAb1fVhVX1IPAXwL8Oaf9bwLur6rvV+b9Vdev0RlX1laq6pqoeqaqrgY/TBSTAg3Qh8/yqeriqrqyqjW3dI8ABSXauqnVVtWpIX75aVRdX1cPAecCLNtHuQeD5Sfasqruq6mtD9vlG4LSquqGq7gLeCRzThsReD/x9VX21qh4A/hiY/pDFy6vqM+28723n9rWqeqiqbgT+ZuDPYcr7q2pjO9drgS+2499B90PEi4f0V1s5w0bbgqOqavf2OmraupumPrShrfe1oa2NwI1t1Z4jHOPZg/uq7gm1N226OQvprn6GSvLSJF9Osj7JHXRXL1P9OQ9YAZyfZG2S/5Fkx6q6G/j11nZdks8n+akhhxkMxXuAJ2/iPsnxwAuA77Qhu18bss9nA98fWP4+3YSivXjsn9U9wPSgfdSfXZIXJPlcG+LcCPx3Hvvf5eaBz/fOsLzrkP5qK2fYaFs3+BP1G+iGb36FbmhnUatP3Xu5G9hloP2zBj6vowuQboMkg8szuIluKGo2H6Mb2lpYVbsBfz3Vn6p6sKr+pKr2pxsq+zW6ITeqakVVvYpumOo7wFkjHGuoqrq+qo6lG2J8P3BhG7Kb6dHva4HnDCzvCzxEFwDrgH2mViTZme4K7VGHm7Z8Bt15LG7DeO9iyD0xTR7DRpPkqcD9dD9l70L30/Ogq4DXJdkl3e/BHD+w7vPAC5O8rl0V/B6PDqPp/hZ4b5LF6fxMkun/4E71aUNV3ZfkYLpABCDJK5L8uyTzgI10w1wPJ9kryWtaENwP3MWjp35vkST/Mcn8qnoEuL2VHwbW0w3bPXeg+ceBtyfZL8mudH+Wn2hToy8EXp3k59tN+z9h9uB4ajvHu9pV2psf7/lo22LYaJKcSzfc80Pg28D0exIfAB6g++n8HAYmD1TVj4CjgffRhdVi4J+HHOs0uhvsX6T7R/RsYOcZ2r0FeE+SO+nubVwwsO5ZdP9wbwSuA/4J+Ajd/5d/SHd1sYHu3sb0m+lbYimwKslddJMFjqmq+9ow2KnAP7f7YocAy+mG+S6j+x2c+4DfBWj3VH6XblLCOuBO4Ba6YNyU/0IXtHfSXaV94gk4H21D4penSXo82pXP7XRDZN8bd3+0dfLKRtJmS/LqNhz5FODPgGv48YQM6TEMG0lb4ki6Yb61dEOOx5TDJBrCYTRJUu+8spEk9c6wkST1zqexNnvuuWctWrRo3N2QpG3KlVde+aOqmj9bO8OmWbRoEStXrhx3NyRpm5Lk+7O3chhNkjQHDBtJUu8MG0lS7wwbSVLvDBtJUu8MG0lS7wwbSVLvDBtJUu/8pc5tzKKTPj/uLkyUG9/3q+PugrRd8MpGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUu97CJsnCJF9Ocl2SVUl+v9VPSfLDJFe11xED27wzyeok301y2EB9aautTnLSQH2/JF9Pcn2STyTZqdV/oi2vbusX9XWekqTZ9Xll8xDwh1X108AhwIlJ9m/rPlBVB7bXxQBt3THAC4GlwIeSzEsyD/gr4HBgf+DYgf28v+1rMXAbcHyrHw/cVlXPBz7Q2kmSxqS3sKmqdVX1zfb5TuA6YMGQTY4Ezq+q+6vqe8Bq4OD2Wl1VN1TVA8D5wJFJAvwycGHb/hzgqIF9ndM+Xwi8srWXJI3BnNyzacNYLwa+3kpvTXJ1kuVJ9mi1BcBNA5utabVN1Z8B3F5VD02rP2pfbf0drf30fp2QZGWSlevXr39c5yhJ2rTewybJrsCngLdV1UbgDOB5wIHAOuDPp5rOsHltQX3Yvh5dqDqzqpZU1ZL58+cPPQ9J0pbrNWyS7EgXNB+tqr8DqKqbq+rhqnoEOItumAy6K5OFA5vvA6wdUv8RsHuSHabVH7Wvtn43YMMTe3aSpFH1ORstwNnAdVV12kB974FmrwWubZ8vAo5pM8n2AxYD3wCuABa3mWc70U0iuKiqCvgy8Pq2/TLgswP7WtY+vx74UmsvSRqDHWZvssVeBvwGcE2Sq1rtXXSzyQ6kG9a6EfgdgKpaleQC4Nt0M9lOrKqHAZK8FVgBzAOWV9Wqtr93AOcn+VPgW3ThRns/L8lquiuaY3o8T0nSLHoLm6r6KjPfO7l4yDanAqfOUL94pu2q6gZ+PAw3WL8POHpz+itJ6o9PEJAk9c6wkST1zrCRJPXOsJEk9c6wkST1zrCRJPXOsJEk9c6wkST1zrCRJPXOsJEk9c6wkST1zrCRJPXOsJEk9c6wkST1zrCRJPXOsJEk9c6wkST1zrCRJPXOsJEk9c6wkST1zrCRJPXOsJEk9c6wkST1zrCRJPXOsJEk9c6wkST1zrCRJPWut7BJsjDJl5Ncl2RVkt9v9acnuSTJ9e19j1ZPktOTrE5ydZKDBva1rLW/PsmygfpLklzTtjk9SYYdQ5I0Hn1e2TwE/GFV/TRwCHBikv2Bk4BLq2oxcGlbBjgcWNxeJwBnQBccwMnAS4GDgZMHwuOM1nZqu6WtvqljSJLGoLewqap1VfXN9vlO4DpgAXAkcE5rdg5wVPt8JHBudb4G7J5kb+Aw4JKq2lBVtwGXAEvbuqdV1eVVVcC50/Y10zEkSWMwJ/dskiwCXgx8HdirqtZBF0jAM1uzBcBNA5utabVh9TUz1BlyDEnSGPQeNkl2BT4FvK2qNg5rOkOttqC+OX07IcnKJCvXr1+/OZtKkjZDr2GTZEe6oPloVf1dK9/chsBo77e0+hpg4cDm+wBrZ6nvM0N92DEeparOrKolVbVk/vz5W3aSkqRZ9TkbLcDZwHVVddrAqouAqRlly4DPDtSPa7PSDgHuaENgK4BDk+zRJgYcCqxo6+5Mckg71nHT9jXTMSRJY7BDj/t+GfAbwDVJrmq1dwHvAy5IcjzwA+Dotu5i4AhgNXAP8CaAqtqQ5L3AFa3de6pqQ/v8ZuDDwM7AF9qLIceQJI1Bb2FTVV9l5vsqAK+coX0BJ25iX8uB5TPUVwIHzFC/daZjSJLGwycISJJ6Z9hIknpn2EiSemfYSJJ6Z9hIknpn2EiSemfYSJJ6N1LYJHnM77JIkjSqUa9s/jrJN5K8JcnuvfZIkjRxRgqbqvr3wBvpHoi5MsnHkryq155JkibGyPdsqup64N3AO4BfAk5P8p0kr+urc5KkyTDqPZufSfIBum/b/GXg1e3rnn8Z+ECP/ZMkTYBRH8T5QeAs4F1Vde9UsarWJnl3Lz2TJE2MUcPmCODeqnoYIMmTgCdX1T1VdV5vvZMkTYRR79n8I913xkzZpdUkSZrVqGHz5Kq6a2qhfd6lny5JkibNqGFzd5KDphaSvAS4d0h7SZL+zaj3bN4GfDLJ2ra8N/Dr/XRJkjRpRgqbqroiyU8BP0n3Vc/fqaoHe+2ZJGlijHplA/CzwKK2zYuTUFXn9tIrSdJEGSlskpwHPA+4Cni4lQswbCRJsxr1ymYJsH9VVZ+dkSRNplFno10LPKvPjkiSJteoVzZ7At9O8g3g/qliVb2ml15JkibKqGFzSp+dkCRNtlGnPv9TkucAi6vqH5PsAszrt2uSpEkx6lcM/DZwIfA3rbQA+ExfnZIkTZZRJwicCLwM2Aj/9kVqzxy2QZLlSW5Jcu1A7ZQkP0xyVXsdMbDunUlWJ/luksMG6ktbbXWSkwbq+yX5epLrk3wiyU6t/hNteXVbv2jEc5Qk9WTUsLm/qh6YWkiyA93v2QzzYWDpDPUPVNWB7XVx29/+wDHAC9s2H0oyL8k84K+Aw4H9gWNbW4D3t30tBm4Djm/144Hbqur5dF/s9v4Rz1GS1JNRw+afkrwL2DnJq4BPAn8/bIOqugzYMOL+jwTOr6r7q+p7wGrg4PZaXVU3tLA7HzgySei+JfTCtv05wFED+zqnfb4QeGVrL0kak1HD5iRgPXAN8DvAxcCWfkPnW5Nc3YbZ9mi1BcBNA23WtNqm6s8Abq+qh6bVH7Wvtv6O1l6SNCYjhU1VPVJVZ1XV0VX1+vZ5S54mcAbdY28OBNYBf97qM1151BbUh+3rMZKckGRlkpXr168f1m9J0uMw6rPRvscM/2BX1XM352BVdfPAPs8CPtcW1wALB5ruA0x9ncFM9R8BuyfZoV29DLaf2teadm9pNzYxnFdVZwJnAixZssRH8UhSTzbn2WhTngwcDTx9cw+WZO+qWtcWX0v3GByAi4CPJTkNeDawGPgG3VXK4iT7AT+km0TwhqqqJF8GXk93H2cZ8NmBfS0DLm/rv+Qz3SRpvEb9pc5bp5X+IslXgT/e1DZJPg68HNgzyRrgZODlSQ6ku0q6ke7+D1W1KskFwLeBh4ATq+rhtp+3Aivofol0eVWtaod4B3B+kj8FvgWc3epnA+clWU13RXPMKOcoSerPqMNoBw0sPonuSuepw7apqmNnKJ89Q22q/anAqTPUL6abkDC9fgPdbLXp9fvorrwkSVuJUYfR/nzg80N0VyX/4QnvjSRpIo06jPaKvjsiSZpcow6j/cGw9VV12hPTHUnSJNqc2Wg/SzfTC+DVwGU8+hcuJUma0eZ8edpBVXUndA/UBD5ZVb/VV8ckSZNj1MfV7As8MLD8ALDoCe+NJGkijXplcx7wjSSfpvsdmdcC5/bWK0nSRBl1NtqpSb4A/EIrvamqvtVftyRJk2TUYTSAXYCNVfWXdM8d26+nPkmSJsyoXwt9Mt3jYd7ZSjsCH+mrU5KkyTLqlc1rgdcAdwNU1VpmeVyNJElTRg2bB9qTkwsgyVP665IkadKMGjYXJPkbuu+Q+W3gH4Gz+uuWJGmSjDob7c+SvArYCPwk8MdVdUmvPZMkTYxZwybJPGBFVf0KYMBIkjbbrMNo7UvM7kmy2xz0R5I0gUZ9gsB9wDVJLqHNSAOoqt/rpVeSpIkyath8vr0kSdpsQ8Mmyb5V9YOqOmeuOiRJmjyz3bP5zNSHJJ/quS+SpAk1W9hk4PNz++yIJGlyzRY2tYnPkiSNbLYJAi9KspHuCmfn9pm2XFX1tF57J0maCEPDpqrmzVVHJEmTa3O+z0aSpC1i2EiSemfYSJJ6Z9hIknrXW9gkWZ7kliTXDtSenuSSJNe39z1aPUlOT7I6ydVJDhrYZllrf32SZQP1lyS5pm1zepIMO4YkaXz6vLL5MLB0Wu0k4NKqWgxc2pYBDgcWt9cJwBnQBQdwMvBS4GDg5IHwOKO1ndpu6SzHkCSNSW9hU1WXARumlY8Epp6zdg5w1ED93Op8je4bQfcGDgMuqaoNVXUb3ffpLG3rnlZVl7evqz532r5mOoYkaUzm+p7NXlW1DqC9P7PVFwA3DbRb02rD6mtmqA87hiRpTLaWCQKZoVZbUN+8gyYnJFmZZOX69es3d3NJ0ojmOmxubkNgtPdbWn0NsHCg3T7A2lnq+8xQH3aMx6iqM6tqSVUtmT9//haflCRpuLkOm4uAqRlly4DPDtSPa7PSDgHuaENgK4BDk+zRJgYcCqxo6+5MckibhXbctH3NdAxJ0piM+k2dmy3Jx4GXA3smWUM3q+x9wAVJjgd+ABzdml8MHAGsBu4B3gRQVRuSvBe4orV7T1VNTTp4M92Mt52BL7QXQ44hSRqT3sKmqo7dxKpXztC2gBM3sZ/lwPIZ6iuBA2ao3zrTMSRJ47O1TBCQJE0ww0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUO8NGktQ7w0aS1DvDRpLUu7GETZIbk1yT5KokK1vt6UkuSXJ9e9+j1ZPk9CSrk1yd5KCB/Sxr7a9Psmyg/pK2/9Vt28z9WUqSpozzyuYVVXVgVS1pyycBl1bVYuDStgxwOLC4vU4AzoAunICTgZcCBwMnTwVUa3PCwHZL+z8dSdKmbE3DaEcC57TP5wBHDdTPrc7XgN2T7A0cBlxSVRuq6jbgEmBpW/e0qrq8qgo4d2BfkqQxGFfYFPDFJFcmOaHV9qqqdQDt/ZmtvgC4aWDbNa02rL5mhrokaUx2GNNxX1ZVa5M8E7gkyXeGtJ3pfkttQf2xO+6C7gSAfffdd3iPJUlbbCxXNlW1tr3fAnya7p7LzW0IjPZ+S2u+Blg4sPk+wNpZ6vvMUJ+pH2dW1ZKqWjJ//vzHe1qSpE2Y87BJ8pQkT536DBwKXAtcBEzNKFsGfLZ9vgg4rs1KOwS4ow2zrQAOTbJHmxhwKLCirbszySFtFtpxA/uSJI3BOIbR9gI+3WYj7wB8rKr+IckVwAVJjgd+ABzd2l8MHAGsBu4B3gRQVRuSvBe4orV7T1VtaJ/fDHwY2Bn4QntJksZkzsOmqm4AXjRD/VbglTPUCzhxE/taDiyfob4SOOBxd1aS9ITYmqY+S5ImlGEjSeqdYSNJ6p1hI0nqnWEjSeqdYSNJ6p1hI0nqnWEjSeqdYSNJ6p1hI0nqnWEjSeqdYSNJ6p1hI0nqnWEjSeqdYSNJ6p1hI0nqnWEjSeqdYSNJ6p1hI0nqnWEjSeqdYSNJ6p1hI0nqnWEjSeqdYSNJ6p1hI0nqnWEjSeqdYSNJ6p1hI0nq3cSGTZKlSb6bZHWSk8bdH0nank1k2CSZB/wVcDiwP3Bskv3H2ytJ2n5NZNgABwOrq+qGqnoAOB84csx9kqTt1g7j7kBPFgA3DSyvAV46vVGSE4AT2uJdSb47B33bXuwJ/GjcnZhN3j/uHmgMtom/m9uQ54zSaFLDJjPU6jGFqjOBM/vvzvYnycqqWjLufkjT+XdzPCZ1GG0NsHBgeR9g7Zj6IknbvUkNmyuAxUn2S7ITcAxw0Zj7JEnbrYkcRquqh5K8FVgBzAOWV9WqMXdre+PwpLZW/t0cg1Q95laGJElPqEkdRpMkbUUMG0lS7wwbSVLvJnKCgOZWkp+ie0LDArrfZ1oLXFRV1421Y5K2Gl7Z6HFJ8g66xwEF+AbdtPMAH/cBqNqaJXnTuPuwPXE2mh6XJP8PeGFVPTitvhOwqqoWj6dn0nBJflBV+467H9sLh9H0eD0CPBv4/rT63m2dNDZJrt7UKmCvuezL9s6w0eP1NuDSJNfz44ef7gs8H3jr2HoldfYCDgNum1YP8H/mvjvbL8NGj0tV/UOSF9B9rcMCuv+J1wBXVNXDY+2cBJ8Ddq2qq6avSPKVue/O9st7NpKk3jkbTZLUO8NGktQ7w0YagyTPSnJ+kn9J8u0kFyd5QZJrx903qQ9OEJDmWJIAnwbOqapjWu1AnIqrCeaVjTT3XgE8WFV/PVVos6Wmpo6TZFGS/53km+31862+d5LLklyV5Nokv5BkXpIPt+Vrkrx97k9JGs4rG2nuHQBcOUubW4BXVdV9SRYDHweWAG8AVlTVqUnmAbsABwILquoAgCS799d1acsYNtLWaUfgg2147WHgBa1+BbA8yY7AZ6rqqiQ3AM9N8j+BzwNfHEuPpSEcRpPm3irgJbO0eTtwM/AiuiuanQCq6jLgF4EfAuclOa6qbmvtvgKcCPxtP92WtpxhI829LwE/keS3pwpJfhZ4zkCb3YB1VfUI8BvAvNbuOcAtVXUWcDZwUJI9gSdV1aeAPwIOmpvTkEbnMJo0x6qqkrwW+Iv2NQz3ATfSPWduyoeATyU5GvgycHervxz4r0keBO4CjqN7TND/SjL1w+M7ez8JaTP5uBpJUu8cRpMk9c6wkST1zrCRJPXOsJEk9c6wkST1zrCRJPXOsJEk9c6wkST17v8DF//MsJh+lHEAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 首先明确，我们拿到数据后，需要做什么事情？\n",
    "# 这里是需要做欺诈检测这个事情，也就是说，我们知道数据里面，存在着正常的数据和异常的信息\n",
    "# 也就是我们需要对信用卡交易信息，进行二分类问题，分成正常交易信息和异常交易信息\n",
    "# 可能这里大部分数据都是正的样本，只有极少部分是负样本\n",
    "\n",
    "# value_counts是为了查看这里有多少不重复的数据值的个数\n",
    "count_classes = pd.value_counts(data['Class'], sort= True).sort_index()\n",
    "count_classes.plot(kind = 'bar')\n",
    "plt.title('Fraud class histogram')  # 欺诈类直方图\n",
    "plt.xlabel('Class')\n",
    "plt.ylabel('Frequency')\n",
    "print(count_classes)\n",
    "\n",
    "# 下图可以知道，  正样本大概有30W，负样本只有500\n",
    "# 也就是它是一个样本极度不规则的数据，我们需要提出怎么解决方案呢？\n",
    "# 需要用到  过采样  和 下采样\n",
    "#\n",
    "#  下采样：对于不均衡数据，我们采用下采样，就是把多的数据取出一部分，将它变成 两个样本数据相差差不多\n",
    "#  过采样：对于较少的数据，我们采用生成虚拟数据，他们也是负样本，这样两个数据也类似了\n",
    "\n",
    "#  综上： 下采样：就是让数据一样少，  过采样：就是让数据一样多"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>V1</th>\n",
       "      <th>V2</th>\n",
       "      <th>V3</th>\n",
       "      <th>V4</th>\n",
       "      <th>V5</th>\n",
       "      <th>V6</th>\n",
       "      <th>V7</th>\n",
       "      <th>V8</th>\n",
       "      <th>V9</th>\n",
       "      <th>V10</th>\n",
       "      <th>...</th>\n",
       "      <th>V21</th>\n",
       "      <th>V22</th>\n",
       "      <th>V23</th>\n",
       "      <th>V24</th>\n",
       "      <th>V25</th>\n",
       "      <th>V26</th>\n",
       "      <th>V27</th>\n",
       "      <th>V28</th>\n",
       "      <th>Class</th>\n",
       "      <th>normAmount</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-1.359807</td>\n",
       "      <td>-0.072781</td>\n",
       "      <td>2.536347</td>\n",
       "      <td>1.378155</td>\n",
       "      <td>-0.338321</td>\n",
       "      <td>0.462388</td>\n",
       "      <td>0.239599</td>\n",
       "      <td>0.098698</td>\n",
       "      <td>0.363787</td>\n",
       "      <td>0.090794</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.018307</td>\n",
       "      <td>0.277838</td>\n",
       "      <td>-0.110474</td>\n",
       "      <td>0.066928</td>\n",
       "      <td>0.128539</td>\n",
       "      <td>-0.189115</td>\n",
       "      <td>0.133558</td>\n",
       "      <td>-0.021053</td>\n",
       "      <td>0</td>\n",
       "      <td>0.244964</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.191857</td>\n",
       "      <td>0.266151</td>\n",
       "      <td>0.166480</td>\n",
       "      <td>0.448154</td>\n",
       "      <td>0.060018</td>\n",
       "      <td>-0.082361</td>\n",
       "      <td>-0.078803</td>\n",
       "      <td>0.085102</td>\n",
       "      <td>-0.255425</td>\n",
       "      <td>-0.166974</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.225775</td>\n",
       "      <td>-0.638672</td>\n",
       "      <td>0.101288</td>\n",
       "      <td>-0.339846</td>\n",
       "      <td>0.167170</td>\n",
       "      <td>0.125895</td>\n",
       "      <td>-0.008983</td>\n",
       "      <td>0.014724</td>\n",
       "      <td>0</td>\n",
       "      <td>-0.342475</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-1.358354</td>\n",
       "      <td>-1.340163</td>\n",
       "      <td>1.773209</td>\n",
       "      <td>0.379780</td>\n",
       "      <td>-0.503198</td>\n",
       "      <td>1.800499</td>\n",
       "      <td>0.791461</td>\n",
       "      <td>0.247676</td>\n",
       "      <td>-1.514654</td>\n",
       "      <td>0.207643</td>\n",
       "      <td>...</td>\n",
       "      <td>0.247998</td>\n",
       "      <td>0.771679</td>\n",
       "      <td>0.909412</td>\n",
       "      <td>-0.689281</td>\n",
       "      <td>-0.327642</td>\n",
       "      <td>-0.139097</td>\n",
       "      <td>-0.055353</td>\n",
       "      <td>-0.059752</td>\n",
       "      <td>0</td>\n",
       "      <td>1.160686</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.966272</td>\n",
       "      <td>-0.185226</td>\n",
       "      <td>1.792993</td>\n",
       "      <td>-0.863291</td>\n",
       "      <td>-0.010309</td>\n",
       "      <td>1.247203</td>\n",
       "      <td>0.237609</td>\n",
       "      <td>0.377436</td>\n",
       "      <td>-1.387024</td>\n",
       "      <td>-0.054952</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.108300</td>\n",
       "      <td>0.005274</td>\n",
       "      <td>-0.190321</td>\n",
       "      <td>-1.175575</td>\n",
       "      <td>0.647376</td>\n",
       "      <td>-0.221929</td>\n",
       "      <td>0.062723</td>\n",
       "      <td>0.061458</td>\n",
       "      <td>0</td>\n",
       "      <td>0.140534</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-1.158233</td>\n",
       "      <td>0.877737</td>\n",
       "      <td>1.548718</td>\n",
       "      <td>0.403034</td>\n",
       "      <td>-0.407193</td>\n",
       "      <td>0.095921</td>\n",
       "      <td>0.592941</td>\n",
       "      <td>-0.270533</td>\n",
       "      <td>0.817739</td>\n",
       "      <td>0.753074</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.009431</td>\n",
       "      <td>0.798278</td>\n",
       "      <td>-0.137458</td>\n",
       "      <td>0.141267</td>\n",
       "      <td>-0.206010</td>\n",
       "      <td>0.502292</td>\n",
       "      <td>0.219422</td>\n",
       "      <td>0.215153</td>\n",
       "      <td>0</td>\n",
       "      <td>-0.073403</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 30 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "         V1        V2        V3        V4        V5        V6        V7  \\\n",
       "0 -1.359807 -0.072781  2.536347  1.378155 -0.338321  0.462388  0.239599   \n",
       "1  1.191857  0.266151  0.166480  0.448154  0.060018 -0.082361 -0.078803   \n",
       "2 -1.358354 -1.340163  1.773209  0.379780 -0.503198  1.800499  0.791461   \n",
       "3 -0.966272 -0.185226  1.792993 -0.863291 -0.010309  1.247203  0.237609   \n",
       "4 -1.158233  0.877737  1.548718  0.403034 -0.407193  0.095921  0.592941   \n",
       "\n",
       "         V8        V9       V10     ...           V21       V22       V23  \\\n",
       "0  0.098698  0.363787  0.090794     ...     -0.018307  0.277838 -0.110474   \n",
       "1  0.085102 -0.255425 -0.166974     ...     -0.225775 -0.638672  0.101288   \n",
       "2  0.247676 -1.514654  0.207643     ...      0.247998  0.771679  0.909412   \n",
       "3  0.377436 -1.387024 -0.054952     ...     -0.108300  0.005274 -0.190321   \n",
       "4 -0.270533  0.817739  0.753074     ...     -0.009431  0.798278 -0.137458   \n",
       "\n",
       "        V24       V25       V26       V27       V28  Class  normAmount  \n",
       "0  0.066928  0.128539 -0.189115  0.133558 -0.021053      0    0.244964  \n",
       "1 -0.339846  0.167170  0.125895 -0.008983  0.014724      0   -0.342475  \n",
       "2 -0.689281 -0.327642 -0.139097 -0.055353 -0.059752      0    1.160686  \n",
       "3 -1.175575  0.647376 -0.221929  0.062723  0.061458      0    0.140534  \n",
       "4  0.141267 -0.206010  0.502292  0.219422  0.215153      0   -0.073403  \n",
       "\n",
       "[5 rows x 30 columns]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用Scikit-learn数据预处理操作\n",
    "from sklearn.preprocessing import StandardScaler \n",
    "\n",
    "# 因为Amonut数值的差异比较大，所以我们要保证 他们数值之间分布差异差不多\n",
    "# 也就是要对他们做归一化处理 和 标准化操作\n",
    "# fit_transform: 是数据做一个变换，  需要将data['Amount']数据，变成 -1,1之间， 最后做成一个新的特征\n",
    "data['normAmount'] = StandardScaler().fit_transform(data['Amount'].values.reshape(-1,1))\n",
    "# 把Time，和原来的Amonut特征，都删除掉， axis表示删除一列\n",
    "data = data.drop(['Time', 'Amount'], axis=1)\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "###### 下面我们采用下采样进行处理(也就是说，让正负样本数一样少) ###############\n",
    "\n",
    "# 首先我们对数据进行切分，把数据变成特征数据和预测数据\n",
    "\n",
    "# 把所有数据取出来，同时不包括 Class这个列, 这样就构成了特征数据\n",
    "X = data.loc[:, data.columns != 'Class']\n",
    "\n",
    "# 把Class这一列取出来， 这样就构成了label值\n",
    "y = data.loc[:, data.columns == 'Class']\n",
    "\n",
    "# 计算 Class = 1 的样本有多少个\n",
    "number_records_fraud = len(data[data.Class == 1])\n",
    "# 我们把这些样本都取出来，通过index来取数据\n",
    "fraud_indices= np.array(data[data.Class ==1].index)\n",
    "\n",
    "\n",
    "#### 我们需要在正样本中进行随机选择 ###\n",
    "\n",
    "# 首先把等于0的索引都取值出来\n",
    "normal_indices = data[data.Class == 0].index\n",
    "\n",
    "# 使用numpy的 choise随机选择， 需要传入 选择数据，选择的个数， replace:表示是否代替\n",
    "random_normal_indices = np.random.choice(normal_indices, number_records_fraud, replace= False)\n",
    "# 将选择出来的数据，变成np数组\n",
    "random_normal_indices = np.array(random_normal_indices)\n",
    "\n",
    "# 将 负样本数据 和 随机选择的正样本数据，进行合并操作\n",
    "under_sample_indices = np.concatenate([fraud_indices, random_normal_indices])\n",
    "\n",
    "under_sample_data = data.iloc[under_sample_indices, :]\n",
    "\n",
    "# 变成测试数据 和 标签数据\n",
    "X_undersample = under_sample_data.loc[:, under_sample_data.columns != 'Class']\n",
    "y_undersample = under_sample_data.loc[:, under_sample_data.columns == 'Class']\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练数据集长度 199364\n",
      "测试数据集长度 85443\n",
      "训练样本总数 284807\n",
      "---\n",
      "下采样训练数据集长度 688\n",
      "下采样测试数据集长度 296\n",
      "下采样训练样本总数 984\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "E:\\Software\\Anaconda3\\lib\\site-packages\\sklearn\\cross_validation.py:41: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.\n",
      "  \"This module will be removed in 0.20.\", DeprecationWarning)\n"
     ]
    }
   ],
   "source": [
    "####  交叉验证 #######\n",
    "\n",
    "# 从train中选择出一部分作为训练集和测试集\n",
    "from sklearn.cross_validation import train_test_split\n",
    "\n",
    "# 对数据集进行切分   random_state：表示随机切分状态为0，以后每次随机的数都能复现\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 0)\n",
    "\n",
    "print(\"训练数据集长度\", len(X_train))\n",
    "print(\"测试数据集长度\", len(X_test))\n",
    "print(\"训练样本总数\", len(X_train) + len(X_test))\n",
    "\n",
    "# 对900多个采样数据集进行切分\n",
    "X_train_undersample, X_test_undersample, y_train_undersample, y_test_undersample = train_test_split(X_undersample, y_undersample,\n",
    "                                                                                                    test_size=0.3, random_state = 0)\n",
    "print(\"---\")\n",
    "print(\"下采样训练数据集长度\", len(X_train_undersample))\n",
    "print(\"下采样测试数据集长度\", len(X_test_undersample))\n",
    "print(\"下采样训练样本总数\", len(X_train_undersample) + len(X_test_undersample))\n",
    "\n",
    "# 我们以后需要使用原始的 85443个测试数据集，进行测试操作\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "#### 模型评估标准 ####\n",
    "#  使用 Recall 召回率，查全率进行衡量   Recall = TP / (TP + FN)\n",
    "#  在检测任务的时候，是使用Recal当成评估标准\n",
    "\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "# 交叉验证评估标准\n",
    "from sklearn.cross_validation import KFold, cross_val_score\n",
    "# confusion_matrix 混淆矩阵\n",
    "from sklearn.metrics import confusion_matrix, recall_score, classification_report\n",
    "\n",
    "def printing_Kfold_scores(x_train_data,y_train_data):\n",
    "    fold = KFold(len(y_train_data),5,shuffle=False) #一第一个参数 训练集的长度，第二个参数为输入的几折交叉验证\n",
    " \n",
    "    # Different C parameters\n",
    "    c_param_range = [0.01,0.1,1,10,100]#传入选择正则化的参数\n",
    "    \n",
    "    # 可视化显示\n",
    "    results_table = pd.DataFrame(index = range(len(c_param_range),2), columns = ['C_parameter','Mean recall score'])\n",
    "    results_table['C_parameter'] = c_param_range\n",
    " \n",
    "    # the k-fold will give 2 lists: train_indices = indices[0], test_indices = indices[1]\n",
    "    j = 0\n",
    "    for c_param in c_param_range:\n",
    "        print('-------------------------------------------')\n",
    "        print('C parameter: ', c_param)\n",
    "        print('-------------------------------------------')\n",
    "        print('')#第一个for循环用来打印在每个正则化参数下的输出\n",
    " \n",
    "        recall_accs = []\n",
    "        for iteration, indices in enumerate(fold,start=1):\n",
    " \n",
    "             # 建立逻辑回归模型  C: 表示惩罚项力度   使用L1正则化惩罚项\n",
    "            lr = LogisticRegression(C = c_param, penalty = 'l1')#传入正则化参数\n",
    " \n",
    "            # 训练模型\n",
    "            lr.fit(x_train_data.iloc[indices[0],:],y_train_data.iloc[indices[0],:].values.ravel())\n",
    " \n",
    "            # 进行预测, 使用交叉验证中的验证集，进行预测\n",
    "            y_pred_undersample = lr.predict(x_train_data.iloc[indices[1],:].values)\n",
    " \n",
    "            # 使用 recall_score进行评分, 这里计算的是召回率\n",
    "            recall_acc = recall_score(y_train_data.iloc[indices[1],:].values,y_pred_undersample)\n",
    "            recall_accs.append(recall_acc)\n",
    "            print('Iteration ', iteration,': recall score = ', recall_acc)\n",
    " \n",
    "        # The mean value of those recall scores is the metric we want to save and get hold of.\n",
    "        results_table.ix[j,'Mean recall score'] = np.mean(recall_accs)\n",
    "        j += 1\n",
    "        print('')\n",
    "        print('Mean recall score ', np.mean(recall_accs))\n",
    "        print('')\n",
    " \n",
    "    best_c = results_table.loc[results_table['Mean recall score'].astype(np.float64).idxmax()]['C_parameter']\n",
    "    \n",
    "    # Finally, we can check which C parameter is the best amongst the chosen.\n",
    "    print('*********************************************************************************')\n",
    "    print('Best model to choose from cross validation is with C parameter = ', best_c)\n",
    "    print('*********************************************************************************')\n",
    "    \n",
    "    return best_c\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-------------------------------------------\n",
      "C parameter:  0.01\n",
      "-------------------------------------------\n",
      "\n",
      "Iteration  1 : recall score =  0.9315068493150684\n",
      "Iteration  2 : recall score =  0.9178082191780822\n",
      "Iteration  3 : recall score =  1.0\n",
      "Iteration  4 : recall score =  0.972972972972973\n",
      "Iteration  5 : recall score =  0.9696969696969697\n",
      "\n",
      "Mean recall score  0.9583970022326186\n",
      "\n",
      "-------------------------------------------\n",
      "C parameter:  0.1\n",
      "-------------------------------------------\n",
      "\n",
      "Iteration  1 : recall score =  0.8493150684931506\n",
      "Iteration  2 : recall score =  0.863013698630137\n",
      "Iteration  3 : recall score =  0.9661016949152542\n",
      "Iteration  4 : recall score =  0.9324324324324325\n",
      "Iteration  5 : recall score =  0.8939393939393939\n",
      "\n",
      "Mean recall score  0.9009604576820737\n",
      "\n",
      "-------------------------------------------\n",
      "C parameter:  1\n",
      "-------------------------------------------\n",
      "\n",
      "Iteration  1 : recall score =  0.8493150684931506\n",
      "Iteration  2 : recall score =  0.863013698630137\n",
      "Iteration  3 : recall score =  0.9830508474576272\n",
      "Iteration  4 : recall score =  0.9459459459459459\n",
      "Iteration  5 : recall score =  0.8939393939393939\n",
      "\n",
      "Mean recall score  0.907052990893251\n",
      "\n",
      "-------------------------------------------\n",
      "C parameter:  10\n",
      "-------------------------------------------\n",
      "\n",
      "Iteration  1 : recall score =  0.8767123287671232\n",
      "Iteration  2 : recall score =  0.8493150684931506\n",
      "Iteration  3 : recall score =  0.9830508474576272\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "E:\\Software\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:47: DeprecationWarning: \n",
      ".ix is deprecated. Please use\n",
      ".loc for label based indexing or\n",
      ".iloc for positional indexing\n",
      "\n",
      "See the documentation here:\n",
      "http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iteration  4 : recall score =  0.9459459459459459\n",
      "Iteration  5 : recall score =  0.9090909090909091\n",
      "\n",
      "Mean recall score  0.9128230199509512\n",
      "\n",
      "-------------------------------------------\n",
      "C parameter:  100\n",
      "-------------------------------------------\n",
      "\n",
      "Iteration  1 : recall score =  0.8904109589041096\n",
      "Iteration  2 : recall score =  0.8493150684931506\n",
      "Iteration  3 : recall score =  0.9661016949152542\n",
      "Iteration  4 : recall score =  0.9459459459459459\n",
      "Iteration  5 : recall score =  0.9090909090909091\n",
      "\n",
      "Mean recall score  0.9121729154698739\n",
      "\n",
      "*********************************************************************************\n",
      "Best model to choose from cross validation is with C parameter =  0.01\n",
      "*********************************************************************************\n"
     ]
    }
   ],
   "source": [
    "best_c = printing_Kfold_scores(X_train_undersample, y_train_undersample)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 混淆矩阵是由一个坐标系组成的， 其中X轴是预测值， Y轴是真实值\n",
    "# 我们可以通过他查看到他的精度， 和 Recall值（召回率 ）\n",
    "# 使用下采样数据集上，进行的测试操作\n",
    "import itertools\n",
    "def plot_confusion_matrix(cm, classes,\n",
    "                          title='Confusion matrix',\n",
    "                          cmap=plt.cm.Blues):\n",
    "    \"\"\"\n",
    "    This function prints and plots the confusion matrix.\n",
    "    \"\"\"\n",
    "    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n",
    "    plt.title(title)\n",
    "    plt.colorbar()\n",
    "    tick_marks = np.arange(len(classes))\n",
    "    plt.xticks(tick_marks, classes, rotation=0)\n",
    "    plt.yticks(tick_marks, classes)\n",
    " \n",
    "    thresh = cm.max() / 2.\n",
    "    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n",
    "        plt.text(j, i, cm[i, j],\n",
    "                 horizontalalignment=\"center\",\n",
    "                 color=\"white\" if cm[i, j] > thresh else \"black\")\n",
    " \n",
    "    plt.tight_layout()\n",
    "    plt.ylabel('True label')\n",
    "    plt.xlabel('Predicted label')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Recall metric in the testing dataset:  0.9183673469387755\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "lr = LogisticRegression(C = best_c, penalty = 'l1')\n",
    "lr.fit(X_train_undersample,y_train_undersample.values.ravel())\n",
    "y_pred = lr.predict(X_test.values)\n",
    " \n",
    "# Compute confusion matrix\n",
    "cnf_matrix = confusion_matrix(y_test,y_pred)\n",
    "np.set_printoptions(precision=2)\n",
    " \n",
    "print(\"Recall metric in the testing dataset: \", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1]))\n",
    " \n",
    "# Plot non-normalized confusion matrix\n",
    "class_names = [0,1]\n",
    "plt.figure()\n",
    "plot_confusion_matrix(cnf_matrix\n",
    "                      , classes=class_names\n",
    "                      , title='Confusion matrix')\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Recall metric in the testing dataset:  0.9183673469387755\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "lr = LogisticRegression(C = best_c, penalty = 'l1')\n",
    "lr.fit(X_train_undersample,y_train_undersample.values.ravel())\n",
    "y_pred = lr.predict(X_test.values)\n",
    " \n",
    "# Compute confusion matrix\n",
    "cnf_matrix = confusion_matrix(y_test,y_pred)\n",
    "np.set_printoptions(precision=2)\n",
    " \n",
    "print(\"Recall metric in the testing dataset: \", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1]))\n",
    " \n",
    "# Plot non-normalized confusion matrix\n",
    "class_names = [0,1]\n",
    "plt.figure()\n",
    "plot_confusion_matrix(cnf_matrix\n",
    "                      , classes=class_names\n",
    "                      , title='Confusion matrix')\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Recall metric in the testing dataset:  1.0\n",
      "Recall metric in the testing dataset:  1.0\n",
      "Recall metric in the testing dataset:  1.0\n",
      "Recall metric in the testing dataset:  0.9931972789115646\n",
      "Recall metric in the testing dataset:  0.9319727891156463\n",
      "Recall metric in the testing dataset:  0.8775510204081632\n",
      "Recall metric in the testing dataset:  0.8367346938775511\n",
      "Recall metric in the testing dataset:  0.7482993197278912\n",
      "Recall metric in the testing dataset:  0.5714285714285714\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x720 with 18 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 我们在做模型预测时，要基于业务层面去考虑，在此案例中我们我们把正常的样本预测成异常的出现8000多个，\n",
    "# 显然是不合适的，看来下采样方法效果也不是很好，那么我们接下里来调整逻辑回归的阈值来看下阈值\n",
    "lr = LogisticRegression(C = 0.01, penalty = 'l1')\n",
    "lr.fit(X_train_undersample,y_train_undersample.values.ravel())\n",
    "# 使用 predict_proba 预测出概率值\n",
    "y_pred_undersample_proba = lr.predict_proba(X_test_undersample.values)\n",
    " \n",
    "thresholds = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]\n",
    " \n",
    "# 指定画图域\n",
    "plt.figure(figsize=(10,10))\n",
    " \n",
    "j = 1\n",
    "for i in thresholds:\n",
    "    \n",
    "    # 这里是和预测值进行比较，得到预测结果\n",
    "    y_test_predictions_high_recall = y_pred_undersample_proba[:,1] > i\n",
    "    \n",
    "    plt.subplot(3,3,j)\n",
    "    j += 1\n",
    "    \n",
    "    # Compute confusion matrix\n",
    "    cnf_matrix = confusion_matrix(y_test_undersample,y_test_predictions_high_recall)\n",
    "    np.set_printoptions(precision=2)\n",
    " \n",
    "    print(\"Recall metric in the testing dataset: \", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1]))\n",
    " \n",
    "    # Plot non-normalized confusion matrix\n",
    "    class_names = [0,1]\n",
    "    plot_confusion_matrix(cnf_matrix\n",
    "                          , classes=class_names\n",
    "                          , title='Threshold >= %s'%i) \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "ename": "ModuleNotFoundError",
     "evalue": "No module named 'sklearn.utils._joblib'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-52-2dc5f846c0a5>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      8\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mpandas\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mpd\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      9\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mimblearn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mover_sampling\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mSMOTE\u001b[0m\u001b[1;31m#引用过采样的smote方法\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 10\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0msklearn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mensemble\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRandomForestClassifier\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     11\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0msklearn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmetrics\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mconfusion_matrix\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     12\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0msklearn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmodel_selection\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mtrain_test_split\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mE:\\Software\\Anaconda3\\lib\\site-packages\\sklearn\\ensemble\\__init__.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      4\u001b[0m \"\"\"\n\u001b[0;32m      5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[0mbase\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mBaseEnsemble\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      7\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[0mforest\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRandomForestClassifier\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      8\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[0mforest\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRandomForestRegressor\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mE:\\Software\\Anaconda3\\lib\\site-packages\\sklearn\\ensemble\\base.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m     13\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mbase\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mMetaEstimatorMixin\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     14\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mutils\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mcheck_random_state\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 15\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mutils\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_joblib\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0meffective_n_jobs\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     16\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;33m.\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexternals\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msix\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     17\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mabc\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mABCMeta\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mabstractmethod\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'sklearn.utils._joblib'"
     ]
    }
   ],
   "source": [
    "####  过采样操作  ####\n",
    "# SMOTE\n",
    "# 对于少数类的每个样本x, 以欧式距离为标准计算它到少数类样本集中所有样本的距离，得到其K近邻\n",
    "# 根据样本不平衡比例设置一个采样比例以确定采样倍率N，对于每个少数类样本x,从其K近邻中随机选择若干个样本，假设选择的近邻为xn。\n",
    "# 对于每个随机选出的近邻xn，分别与原来样本构建新的样本\n",
    "# X1 = x + rand(0, 1)*(x2 - x)\n",
    "\n",
    "import pandas as pd\n",
    "from imblearn.over_sampling import SMOTE#引用过采样的smote方法\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.metrics import confusion_matrix\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "227454\n",
      "-------------------------------------------\n",
      "C parameter:  0.01\n",
      "-------------------------------------------\n",
      "\n",
      "Iteration  1 : recall score =  0.8903225806451613\n",
      "Iteration  2 : recall score =  0.8947368421052632\n",
      "Iteration  3 : recall score =  0.9687285603629523\n",
      "Iteration  4 : recall score =  0.9578923071850166\n",
      "Iteration  5 : recall score =  0.958397907255361\n",
      "\n",
      "Mean recall score  0.9340156395107508\n",
      "\n",
      "-------------------------------------------\n",
      "C parameter:  0.1\n",
      "-------------------------------------------\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "E:\\Software\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:47: DeprecationWarning: \n",
      ".ix is deprecated. Please use\n",
      ".loc for label based indexing or\n",
      ".iloc for positional indexing\n",
      "\n",
      "See the documentation here:\n",
      "http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iteration  1 : recall score =  0.8903225806451613\n",
      "Iteration  2 : recall score =  0.8947368421052632\n",
      "Iteration  3 : recall score =  0.9696802036073918\n",
      "Iteration  4 : recall score =  0.9599366900781482\n",
      "Iteration  5 : recall score =  0.9582330376672052\n",
      "\n",
      "Mean recall score  0.9345818708206339\n",
      "\n",
      "-------------------------------------------\n",
      "C parameter:  1\n",
      "-------------------------------------------\n",
      "\n",
      "Iteration  1 : recall score =  0.8903225806451613\n",
      "Iteration  2 : recall score =  0.8947368421052632\n",
      "Iteration  3 : recall score =  0.9702777470399468\n",
      "Iteration  4 : recall score =  0.9588485507963201\n",
      "Iteration  5 : recall score =  0.9607720293248041\n",
      "\n",
      "Mean recall score  0.9349915499822992\n",
      "\n",
      "-------------------------------------------\n",
      "C parameter:  10\n",
      "-------------------------------------------\n",
      "\n",
      "Iteration  1 : recall score =  0.8903225806451613\n",
      "Iteration  2 : recall score =  0.8947368421052632\n",
      "Iteration  3 : recall score =  0.9702998782781896\n",
      "Iteration  4 : recall score =  0.9591672986667545\n",
      "Iteration  5 : recall score =  0.9609478902188369\n",
      "\n",
      "Mean recall score  0.935094897982841\n",
      "\n",
      "-------------------------------------------\n",
      "C parameter:  100\n",
      "-------------------------------------------\n",
      "\n",
      "Iteration  1 : recall score =  0.8903225806451613\n",
      "Iteration  2 : recall score =  0.8947368421052632\n",
      "Iteration  3 : recall score =  0.9705433218988603\n",
      "Iteration  4 : recall score =  0.9602444466427056\n",
      "Iteration  5 : recall score =  0.960739055407173\n",
      "\n",
      "Mean recall score  0.9353172493398327\n",
      "\n",
      "*********************************************************************************\n",
      "Best model to choose from cross validation is with C parameter =  100.0\n",
      "*********************************************************************************\n"
     ]
    }
   ],
   "source": [
    "credit_cards=pd.read_csv('creditcard.csv')\n",
    " \n",
    "columns=credit_cards.columns\n",
    "# The labels are in the last column ('Class'). Simply remove it to obtain features columns\n",
    "features_columns=columns.delete(len(columns)-1)\n",
    " \n",
    "features=credit_cards[features_columns]\n",
    "labels=credit_cards['Class']\n",
    "features_train, features_test, labels_train, labels_test = train_test_split(features, \n",
    "                                                                            labels, \n",
    "                                                                            test_size=0.2, \n",
    "                                                                            random_state=0)\n",
    "\n",
    "# 定义SMOTE模型，random_state相当于随机数种子的作用\n",
    "oversampler=SMOTE(random_state=0)\n",
    "\n",
    "# 将原始数据拿过来 ，自动生成负样本 \n",
    "os_features,os_labels=oversampler.fit_sample(features_train,labels_train)\n",
    "\n",
    "# 从上述代码中可以看出，SMOTE模型默认生成一比一的数据，如果想生成其他比例的数据，\n",
    "# 可以使用radio参数。不仅可以处理二分类问题，同样适用于多分类问题\n",
    "\n",
    "# imblearn中上采样接口提供了随机上采样RandomOverSampler，SMOTE，ADASYN三种方式，调用方式和主要参数基本一样。\n",
    "# 下采样接口中也提供了多种方法，以RandomUnderSampler为例。\n",
    "\n",
    "# 最后打印出负样本的数量，我们能够发现，正负样本数已经达到均衡效果\n",
    "print(len(os_labels[os_labels==1]))\n",
    "\n",
    "# 下面使用过采样的方式，查看得到的精度是多高\n",
    "os_features = pd.DataFrame(os_features)\n",
    "os_labels = pd.DataFrame(os_labels)\n",
    "best_c = printing_Kfold_scores(os_features,os_labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lr = LogisticRegression(C = best_c, penalty = 'l1')\n",
    "lr.fit(os_features,os_labels.values.ravel())\n",
    "y_pred = lr.predict(features_test.values)\n",
    " \n",
    "# Compute confusion matrix\n",
    "cnf_matrix = confusion_matrix(labels_test,y_pred)\n",
    "np.set_printoptions(precision=2)\n",
    " \n",
    "print(\"Recall metric in the testing dataset: \", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1]))\n",
    " \n",
    "# Plot non-normalized confusion matrix\n",
    "class_names = [0,1]\n",
    "plt.figure()\n",
    "plot_confusion_matrix(cnf_matrix\n",
    "                      , classes=class_names\n",
    "                      , title='Confusion matrix')\n",
    "plt.show()\n",
    "\n",
    "# 总结：对于样本不均衡的数据，我们能够利用的数据越多越好，也就是说一般采用过采样，效果会比较好\n",
    "# 一般下采样的时候，误杀率会偏高"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
